package net.sparrow.util;

import java.io.PrintStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;

import org.lwjgl.input.Keyboard;

import net.minecraft.src.Entity;
import net.minecraft.src.EntityLiving;
import net.minecraft.src.HttpUtil;
import net.minecraft.src.MathHelper;
import net.minecraft.src.Minecraft;
import net.minecraft.src.Packet;
import net.minecraft.src.RenderManager;
import net.minecraft.src.Session;
import net.sparrow.Sparrow;
import net.sparrow.data.UtilFile;

public class Util {

	public static SpLogLevel logLevel = SpLogLevel.DEBUG; //TODO make this togglable/chngable

	public static void print(String s) {
		print(s, SpLogLevel.NORMAL);
	}

	public static void print(String s, SpLogLevel lvl) {
		if(lvl == SpLogLevel.DEBUG) {
			if(logLevel == SpLogLevel.NORMAL) {
				//we are in normal print mode, don't show debug messages
				return;
			}

			s = "[DEBUG] " + s;
		}

		UtilFile.fileOut.println(s);
		System.out.println(s);
	}

	public static void debug(String s) {
		print(s, SpLogLevel.DEBUG);
	}

	public static boolean inGame() {
		return Minecraft.getMinecraft().theWorld != null;
	}
	
	public static void sendPacket(Packet p) {
		Sparrow.mc().player().sendQueue.addToSendQueue(p);
	}

	public enum SpLogLevel {
		NORMAL, //critical (game-ending) errors, important info like username, server, etc
		DEBUG; // any logging intended to weed out bugs. backend errors, hookup errors, logic failures, etc
	}

	public static Class convertClassToString(Class clazz) { return clazz;}

	public static void faceEntity(Entity ent)
	{
		double var4 = ent.posX - Sparrow.mc().player().posX;
		double var6 = ent.posZ - Sparrow.mc().player().posZ;
		double var8;

		if (ent instanceof EntityLiving)
		{
			EntityLiving var10 = (EntityLiving)ent;
			var8 = var10.posY + (double)var10.getEyeHeight() - (Sparrow.mc().player().posY + (double)Sparrow.mc().player().getEyeHeight());
		}
		else
		{
			var8 = (ent.boundingBox.minY + ent.boundingBox.maxY) / 2.0D - (Sparrow.mc().player().posY + (double)Sparrow.mc().player().getEyeHeight());
		}

		double var14 = (double)MathHelper.sqrt_double(var4 * var4 + var6 * var6);
		float var12 = (float)(Math.atan2(var6, var4) * 180.0D / Math.PI) - 90.0F;
		float var13 = (float)(-(Math.atan2(var8, var14) * 180.0D / Math.PI));
		Sparrow.mc().player().rotationPitch = var13;
		Sparrow.mc().player().rotationYaw = var12;
	}

	public static double getFovChg(Entity ent) {
		double xDis = ent.posX - Sparrow.mc().player().posX;
		double zDis = ent.posZ - Sparrow.mc().player().posZ;
		float var12 = (float)(Math.atan2(zDis, xDis) * 180.0D / Math.PI) - 90.0F;
		float var4 = MathHelper.wrapAngleTo180_float(var12 - Sparrow.mc().player().rotationYaw);
		return (int) Math.abs(var4);
	}
	public static Object convertStringToObject(String input) {

		if(input.equals("true")) {
			return Boolean.TRUE;
		}

		if(input.equals("false")) {
			return Boolean.FALSE;
		}

		try {
			return Integer.parseInt(input);
		} catch(Exception e) {}

		try {
			return Double.parseDouble(input);
		} catch(Exception e) {}

		return input;
	}


	public static SpLocation getRenderLocationOfEntity(Entity ent) {
		if (ent.ticksExisted == 0)
		{
			ent.lastTickPosX = ent.posX;
			ent.lastTickPosY = ent.posY;
			ent.lastTickPosZ = ent.posZ;
		}
		//RenderManager.java: renderEntity()
		Float par2 = Minecraft.getMinecraft().timer.renderPartialTicks;
		double var3 = ent.lastTickPosX + (ent.posX - ent.lastTickPosX) * (double)par2;
		double var5 = ent.lastTickPosY + (ent.posY - ent.lastTickPosY) * (double)par2;
		double var7 = ent.lastTickPosZ + (ent.posZ - ent.lastTickPosZ) * (double)par2;
		var3 -= RenderManager.renderPosX;
		var5 -= RenderManager.renderPosY;
		var7 -= RenderManager.renderPosZ;
		return new SpLocation(var3, var5, var7);
	}

	/*http://stackoverflow.com/questions/2282728/java-replacelast
	 * A short explanation (in case of the regex being AB):

(?s)     # enable dot-all option
A        # match the character 'A'
B        # match the character 'B'
(?!      # start negative look ahead
  .*?    #   match any character and repeat it zero or more times, reluctantly
  A      #   match the character 'A'
  B      #   match the character 'B'
)        # end negative look ahead
	 */
	public static String replaceLast(String text, String regex, String replacement) {
		return text.replaceFirst("(?s)"+regex+"(?!.*?"+regex+")", replacement);
	}

	public static boolean isValidKey(int i) {
		switch(i) {
		case Keyboard.KEY_LSHIFT:
		case Keyboard.KEY_RSHIFT:
		case Keyboard.KEY_F1:
		case Keyboard.KEY_F2:
		case Keyboard.KEY_F3:
		case Keyboard.KEY_F4:
		case Keyboard.KEY_F5:
		case Keyboard.KEY_F6:
		case Keyboard.KEY_F7:
		case Keyboard.KEY_F8:
		case Keyboard.KEY_F9:
		case Keyboard.KEY_F10:
		case Keyboard.KEY_F11:
		case Keyboard.KEY_F12:
		case Keyboard.KEY_TAB:
		case Keyboard.KEY_CAPITAL:
		case Keyboard.KEY_LCONTROL:
		case Keyboard.KEY_RCONTROL:
		case Keyboard.KEY_DELETE:
		case Keyboard.KEY_SYSRQ:
		case Keyboard.KEY_RETURN:
		case Keyboard.KEY_INSERT:
		case Keyboard.KEY_NUMLOCK:
		case Keyboard.KEY_DOWN:
		case Keyboard.KEY_LEFT:
		case Keyboard.KEY_BACK:
		case Keyboard.KEY_RIGHT:
		case Keyboard.KEY_UP:
		case Keyboard.KEY_HOME:
		case Keyboard.KEY_END:
		case Keyboard.KEY_LMENU:
		case Keyboard.KEY_RMENU:
		case Keyboard.KEY_LMETA:
		case Keyboard.KEY_RMETA:
		case Keyboard.KEY_ESCAPE:
			return false;


		default:
			return true;
		}
	}


	public static void login(String username, String pass) {
		HashMap var3 = new HashMap();
		var3.put("user", username);
		var3.put("password", pass);
		var3.put("version", Integer.valueOf(13));
		String var4;

		try
		{
			var4 = HttpUtil.sendPost(null, new URL("http://login.minecraft.net/"), var3, false);
		}
		catch (MalformedURLException var6)
		{
			var6.printStackTrace();
			return;
		}

		if (var4 != null && var4.length() != 0)
		{
			if (!var4.contains(":"))
			{
				System.out.println("Failed to authenticate: " + var4);
				Util.print("Failed to authenticate: " + var4);
				return;
			}
			else
			{
				String[] var5 = var4.split(":");
				Session ses = new Session(var5[2],var5[3]);
				Sparrow.mc().minecraft().session = ses;
			}
		}
		else
		{
			System.out.println("Failed to authenticate: Can\'t connect to minecraft.net");
			Util.print("Failed to authenticate: Can\'t connect to minecraft.net");
		}
	}
}
